package org.suwenqian.airoleplayingchatbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.suwenqian.airoleplayingchatbackend.dao.dto.req.VoiceChatReqDTO;
import org.suwenqian.airoleplayingchatbackend.dao.entity.RoleDO;
import org.suwenqian.airoleplayingchatbackend.dao.mapper.RoleMapper;
import org.suwenqian.airoleplayingchatbackend.service.AliyunTtsService;
import org.suwenqian.airoleplayingchatbackend.service.VoiceChatService;


import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
@RequiredArgsConstructor
public class VoiceChatServiceImpl implements VoiceChatService {

    private final ChatClient.Builder chatClientBuilder;
    private final ChatMemory redisChatMemory;
    private final RoleMapper roleMapper;
    private final AliyunTtsService aliyunTtsService;

    /**
     * 默认采样率
     */
    private final static Integer SAMPLE_RATE = 16000;

    @Override
    @Async("voiceChatExecutor")
    public CompletableFuture<ResponseEntity<Resource>> voiceChat( VoiceChatReqDTO requestParm) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                // 1. 识别语音文件并转为文字
                String content = aliyunTtsService.recognizeSpeech(requestParm.getAudioFile(), SAMPLE_RATE).get();

                // 2. 使用文字生成对话
                LambdaQueryWrapper<RoleDO> queryWrapper = Wrappers.lambdaQuery(RoleDO.class)
                        .eq(RoleDO::getId, requestParm.getRoleId());
                RoleDO roleDO = roleMapper.selectOne(queryWrapper);
                if (roleDO == null) {
                    log.error("[语音对话聊天]： 为在数据库中找到该角色信息- - 角色ID： {}", requestParm.getRoleId());
                    throw new IllegalArgumentException("Role with ID " + requestParm.getRoleId() + " not found");
                }
                ChatClient dynamicChatClient = chatClientBuilder
                        .defaultSystem(roleDO.getPromptTemplate()) // 角色设定
                        .defaultAdvisors(
                                MessageChatMemoryAdvisor.builder(redisChatMemory).build(),
                                new SimpleLoggerAdvisor()
                        )
                        .build();

                String response = dynamicChatClient.prompt()
                        .user(content)
                        .advisors(a -> a.param("chatMemoryConversationIdKey", requestParm.getConversationId()))
                        .call()
                        .content();

                // 3. 文字转为语音文件返回
                byte[] audioBytes = aliyunTtsService.synthesizeChineseSpeech(response).get();
                ByteArrayResource resource = new ByteArrayResource(audioBytes);

                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType("audio/mpeg"))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=response.mp3")
                        .body(resource);
            } catch (Exception e) {
                throw new RuntimeException("Error processing voice chat request", e);
            }
        });
    }

}
